﻿using Azure.Core;
using Dapper;
using System;
using System.Collections.Generic;
using System.Data;
using System.Diagnostics;
using System.Linq;
using System.Runtime.CompilerServices;
using System.Text;

namespace Asion.Dapper.Model
{
    /// <summary>
    /// 连接查询关联请求
    /// </summary>
    public class JoinPageQueryConditionRequest
    {
        public JoinPageQueryConditionRequest()
        {
         
            SideTable = new Dictionary<string, string>();
        }
        public JoinPageQueryConditionRequest(string columns, string mainTable,string mainWhere)
        {
            Columns = columns;
            MainTable = mainTable;
            MainWhere= mainWhere;
            SideTable = new Dictionary<string, string>();
        }
        /// <summary>
        /// 列
        /// </summary>
        public string Columns { get; set; }



        /// <summary>
        /// order by 
        /// </summary>
        public string OrderBy { get; set; }


        /// <summary>
        /// 
        /// </summary>
        public string MainTable { get; set; }

        /// <summary>
        /// 
        /// </summary>
        public string MainWhere { get; set; }


        /// <summary>
        /// 附表条件
        /// </summary>
        public Dictionary<string, string> SideTable { get; set; }


        /// <summary>
        /// 附表条件
        /// </summary>
        public string SideWhere { get; set; }


        /// <summary>
        /// 页码
        /// </summary>
        public int PageNumber { get; set; } = 1;

        /// <summary>
        /// 页数
        /// </summary>
        public int RowsPerPage { get; set; } = DapperConfiguration.default_rows_page;


        /// <summary>
        /// 参数
        /// </summary>
        public object Parameter { get; set; }

        private const string string_empty = " ";

        public JoinPageQueryConditionRequest AppendColumn(string column)
        {
            this.Columns += string_empty + column;
            return this;
        }

        public JoinPageQueryConditionRequest AppendOrderBy(string orderBy)
        {
            this.OrderBy += string_empty + orderBy;
            return this;
        }

        public JoinPageQueryConditionRequest AppendMainTable(string mainTable)
        {
            this.MainTable += string_empty + mainTable;
            return this;
        }


        public JoinPageQueryConditionRequest AppendSideTable(string key, string sideTable)
        {
            if (this.SideTable.ContainsKey(key))
            {
                this.SideTable[key] += string_empty + sideTable;
            }
            else
            {
                this.SideTable.Add(key, string_empty + sideTable);
            }
            return this;
        }


        public JoinPageQueryConditionRequest AppendMainWhere(string mainWhere)
        {
            this.MainWhere += string_empty + mainWhere;
            return this;
        }


        public JoinPageQueryConditionRequest AppendSideWhere(string sideWhere)
        {
            this.SideWhere += string_empty + sideWhere;
            return this;
        }

        public JoinPageQueryConditionRequest SetParamter(object param)
        {
            this.Parameter = param;
            return this;
        }


        internal Tuple<string, string> BuildSql()
        {
            //将附表构建出来
            var sideSql = "";
            foreach (var item in SideTable)
            {
                sideSql += item.Value;
            }

            var countColmunsSql = string.Empty;
            //如果包含distnct 和 as 需要处理一下 不然 select count ( a as b) 会报错
            //  as 前后输入空格是因为可能会出现某个字段刚好是as的情况
            if (this.Columns.Contains("distinct") && this.Columns.Contains(" as "))
            {
                var columns = this.Columns.Split(',').ToArray();
                var countColumnsList = new List<string>();
                foreach (var item in columns)
                {
                    if (item.Contains(" as "))
                    {
                        countColumnsList.Add(item.Split(new string[] { " as " }, StringSplitOptions.None)[0]);
                    }
                    else
                    {
                        countColumnsList.Add(item);
                    }
                }
                countColmunsSql = string.Join(",", countColumnsList);
            }
            else
            {
                countColmunsSql = this.Columns;
            }

            string getListSql = $"select {this.Columns}  from  {this.MainTable} {sideSql} where 1=1 {this.MainWhere} {this.SideWhere} {this.OrderBy} limit {(this.PageNumber - 1) * this.RowsPerPage},{this.RowsPerPage}";
            string getCountSql = $"select count({countColmunsSql}) from {this.MainTable} {sideSql} where 1=1 {this.MainWhere} {this.SideWhere} ";

            return Tuple.Create(getListSql, getCountSql);
        }

        public Tuple<string, string> PrintSql()
        {
            //只有调试模式打印sql
            if (Debugger.IsAttached)
            {
                var sql = BuildSql();

                //将参数放到sql中。
                //借用dapper的dynamtice来打印

                var sql1 = sql.Item1;
                var sql2 = sql.Item2;
                var type = this.Parameter.GetType();
                foreach (var item in type.GetProperties())
                {
                    var propertyType = item.PropertyType;
                    var value = item.GetValue(this.Parameter);
                    if (value is not null)
                    {
                        string replaceValue = "";
                        //数值类型
                        var intTypes = new Type[] { typeof(int), typeof(long), typeof(short), typeof(byte), typeof(decimal), typeof(double), typeof(float) };
                        if (intTypes.Contains(propertyType))
                        {
                            replaceValue = value.ToString();
                        }
                        else if (propertyType == typeof(DateTime) || propertyType == typeof(Nullable<DateTime>))//时间类型
                        {
                            replaceValue = "'" + value.ToString() + "'";
                        }
                        else if (propertyType == typeof(string) || propertyType == typeof(String))
                        {
                            replaceValue = "'" + value.ToString() + "'";
                        }
                        else if (propertyType == typeof(List<int>)) //int 类型
                        {
                            var intList = value as List<int>;
                            if (!intList.Any())
                                continue;
                            replaceValue = "(" + string.Join(",", intList) + ")";

                        }
                        else if (propertyType == typeof(List<string>) || propertyType == typeof(List<String>)) //string 类型
                        {
                            var intList = value as List<string>;
                            if (!intList.Any())
                                continue;

                            replaceValue += "(";
                            foreach (var itemList in intList)
                            {
                                replaceValue += "'" + itemList + "',";
                            }
                            replaceValue = replaceValue.TrimEnd(',');
                            replaceValue += ")";
                        }


                        sql1 = sql1.Replace("@" + item.Name, replaceValue);
                        sql2 = sql2.Replace("@" + item.Name, replaceValue);

                    }

                    Console.WriteLine("get list sql:" + sql1);
                    Console.WriteLine("get list sql:" + sql2);

                }


                return new Tuple<string, string>(sql1, sql2);

            }
            return new Tuple<string, string>("", "");
        }


        public Tuple<string, string> GetSql()
        {
            return BuildSql();
        }
    }
}
